import { useKadenaWallet } from '@kadena/wallet-adapter-react'
import { useLocalStorage } from '@sushiswap/hooks'
import React, {
  createContext,
  useCallback,
  useContext,
  useState,
  useMemo,
  type ReactNode,
  useEffect,
} from 'react'

type WalletContextType = {
  currentWallet: string | null
  activeAccount: {
    accountName: string
    networkId: string
    contract: string
    guard: {
      keys: string[]
      pred: string
    }
    chainAccounts: string[]
  } | null
  handleConnect: (walletAdapterName: string) => Promise<void>
  handleDisconnect: () => Promise<void>
  setCurrentWallet: (wallet: string) => void
  adapters: {
    name: string
    detected: boolean
    imageURI: string
    installUrl: string
  }[]
  isConnected: boolean
  isConnecting: boolean
}

const KadenaWalletContext = createContext<WalletContextType | undefined>(
  undefined,
)

type KadenaWalletProviderProps = {
  children: ReactNode
}
export const KADENA_WALLET_ADAPTER_ICONS = {
  Snap: '',
  Ecko: '',
  WalletConnect:
    '',
}
export const ADAPTER_INSTALL_URLS = {
  Ecko: 'https://wallet.ecko.finance/',
}

export const KadenaWalletProvider = ({
  children,
}: KadenaWalletProviderProps) => {
  const { client } = useKadenaWallet()
  const [currentWallet, setCurrentWallet] = useState<string | null>(null)
  const [activeAccount, setActiveAccount] = useState<any>(null)
  const [isConnected, setIsConnected] = useState(false)
  const [isConnecting, setIsConnecting] = useState(false)
  const [lastWallet, setLastWallet] = useLocalStorage<string | null>(
    'sushi.kadena.wallet',
    null,
  )
  const [hasAttemptedAutoConnect, setHasAttemptedAutoConnect] = useState(false)

  const handleConnect = useCallback(
    async (walletAdapterName: string) => {
      if (!walletAdapterName) return
      if (walletAdapterName !== 'WalletConnect') {
        setIsConnecting(true)
      }
      try {
        const accountInfo = await client.connect(walletAdapterName)
        setLastWallet(walletAdapterName)
        setActiveAccount(accountInfo)
        setCurrentWallet(walletAdapterName)
        setIsConnected(true)
      } catch (error) {
        console.error('Failed to connect wallet:', error)
      } finally {
        setIsConnecting(false)
      }
    },
    [setLastWallet, client],
  )

  const handleDisconnect = useCallback(async () => {
    if (currentWallet) {
      await client.disconnect(currentWallet)
      setLastWallet(null)
      setActiveAccount(null)
      setCurrentWallet(null)
      setIsConnected(false)
    }
  }, [client, currentWallet, setLastWallet])

  //autoconnect start
  const activeAdapters = client.getDetectedAdapters()
  useEffect(() => {
    const connectWallet = async () => {
      try {
        if (
          lastWallet &&
          activeAdapters.find((adapter) => adapter.name === lastWallet) &&
          !hasAttemptedAutoConnect
        ) {
          setHasAttemptedAutoConnect(true)
          await handleConnect(lastWallet)
        }
      } catch (error) {
        console.log('Auto connect failed', error)
      }
    }
    connectWallet()
  }, [activeAdapters, lastWallet, hasAttemptedAutoConnect, handleConnect])
  //autoconnect end

  const walletAdapters = client.getProviders().map((adapter) => ({
    name: adapter.name,
    detected: adapter.detected,
    imageURI:
      KADENA_WALLET_ADAPTER_ICONS[
        adapter.name as keyof typeof KADENA_WALLET_ADAPTER_ICONS
      ] || '',
    installUrl:
      ADAPTER_INSTALL_URLS[adapter.name as keyof typeof ADAPTER_INSTALL_URLS] ||
      '',
  }))

  const contextValue = useMemo(
    () => ({
      currentWallet,
      activeAccount,
      handleConnect,
      handleDisconnect,
      setCurrentWallet,
      adapters: walletAdapters,
      isConnected,
      isConnecting,
    }),
    [
      currentWallet,
      activeAccount,
      handleConnect,
      handleDisconnect,
      walletAdapters,
      isConnected,
      isConnecting,
    ],
  )

  return (
    <KadenaWalletContext.Provider value={contextValue}>
      {children}
    </KadenaWalletContext.Provider>
  )
}

export const useKadena = (): WalletContextType => {
  const context = useContext(KadenaWalletContext)
  if (!context)
    throw new Error('useKadena must be used within a KadenaWalletProvider')
  return context
}
